package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductSkuService;
import com.spzx.product.api.dto.ProductSkuVo;
import com.spzx.product.api.dto.SkuPriceVo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : 戚欣扬
 * @Description :
 */
@Service
@RequiredArgsConstructor
public class CartInfoServiceImpl implements ICartService {

    private final RedisTemplate redisTemplate;
    private final RemoteProductSkuService remoteProductSkuService;
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        String cartKey = getCartKey();
        // set cart key
        String key = skuId.toString();
        //1. 判断购物车中是否有该商品
        // 第一种操作数据库的方法：Boolean exists = redisTemplate.opsForHash().hasKey(cartKey, key);
        //2.先绑定Hash
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        Boolean exists = boundHashOperations.hasKey(key);
        //2.存在更新数量，上限99
        if(exists){
            //2.1 get cartInfo
            CartInfo cartInfo = boundHashOperations.get(key);
            Integer num = cartInfo.getSkuNum()+skuNum;
            //2.2 update cartInfo
            cartInfo.setSkuNum(num>99?99:num);
            cartInfo.setUpdateTime(new Date());
            //2.3 write back cartInfo
           boundHashOperations.put(key,cartInfo);
        }else{
            //3.不存在则创建用户购物车的商品对象，限制最多加购商品50个，并保存到购物车中
            //3.1 check cur cart size
            Long cartSize = boundHashOperations.size()+1;
            if(cartSize>50){
                throw new RuntimeException("商品种类超过上限！");
            }
            //3.2 build cart
            R<ProductSkuVo> result = remoteProductSkuService.getProductSku(skuId, SecurityConstants.INNER);
            if(result.getCode() == R.FAIL){
                throw new ServiceException(result.getMsg());
            }
            ProductSkuVo productSkuVo = result.getData();
            CartInfo cartInfo = new CartInfo();
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuNum(skuNum>99?99:skuNum);
            cartInfo.setUserId(SecurityUtils.getUserId());
            //todo:有空完成价格修正,实时价格应该什么时候去查，放入购物车时候的价格
            cartInfo.setCartPrice(productSkuVo.getSalePrice());
            cartInfo.setSkuPrice(productSkuVo.getSalePrice());
            cartInfo.setThumbImg(productSkuVo.getThumbImg());
            cartInfo.setSkuName(productSkuVo.getSkuName());
            cartInfo.setCreateTime(new Date());
            boundHashOperations.put(key,cartInfo);
        }

    }

    @Override
    public List<CartInfo> getCartList() {
        // todo : 这里查询购物车实时价格？
        //1.get cur user cartKey
        String cartKey = getCartKey();
        //2.get data
        BoundHashOperations hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if(!cartInfoList.isEmpty()){
            List<CartInfo> result = cartInfoList.stream()
                    //降序
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return result;
        }
        return new ArrayList<CartInfo>();
    }

    @Override
    public void deleteCart(Long skuId) {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        hashOperations.delete(skuId.toString());
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 先获取用户选择的商品
        if (Boolean.TRUE.equals(hashOperations.hasKey(skuId.toString()))) {
            CartInfo cartInfoUpd = hashOperations.get(skuId.toString());
            // cartInfoUpd 写回缓存
            cartInfoUpd.setIsChecked(isChecked);
            // 更新缓存
            hashOperations.put(skuId.toString(), cartInfoUpd);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOperations.values();
        if(cartInfoList.isEmpty() || cartInfoList==null){
            return;
        }
        cartInfoList.forEach(item -> {
            CartInfo cartInfoUpd = hashOperations.get(item.getSkuId().toString());
            cartInfoUpd.setIsChecked(isChecked);

            // 更新缓存
            hashOperations.put(item.getSkuId().toString(), cartInfoUpd);
        });
    }

    @Override
    public void clearCart() {
        String cartKey = getCartKey();
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList() {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOperations.values();
        if(!cartInfoList.isEmpty() && cartInfoList!=null){
            List<CartInfo> list = cartInfoList.stream()
                    .filter(item -> item.getIsChecked().intValue() == 1)
                    .toList();
            return list;
        }
        return null;
    }

    @Override
    public Boolean deleteCartCheckedList() {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartCachInfoList = hashOperations.values();
        if (!CollectionUtils.isEmpty(cartCachInfoList)) {
            for (CartInfo cartInfo : cartCachInfoList) {
                // 删除选中的商品
                if (cartInfo.getIsChecked().intValue() == 1) {
                    hashOperations.delete(cartInfo.getSkuId().toString());
                }
            }
        }
        return true;
    }

    @Override
    public Boolean updateCartPrice() {
        String cartKey = getCartKey();
        //获取购物车的商品信息
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartCachInfoList = hashOperations.values();
        if (!CollectionUtils.isEmpty(cartCachInfoList)) {
            //遍历 商品并远程调用更新商品实时价格
            for (CartInfo cartInfo : cartCachInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1) {
                    //查询实时价格
                    SkuPriceVo skuPrice = remoteProductSkuService
                            .getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER)
                            .getData();

                    //放入购物车时价格
                    cartInfo.setCartPrice(skuPrice.getSalePrice());

                    //实时价格
                    cartInfo.setSkuPrice(skuPrice.getSalePrice());
                    hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
                }
            }
        }
        return true;
    }

    public String getCartKey(){
        Long userId = SecurityUtils.getUserId();
        // set redis key
        return "user:cart:"+userId;
    }
}


